package handlers

import (
	"data_service/models"
	"data_service/server/websocket"
	"fmt"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

// 全局WebSocket服务器实例
var globalWebSocketServer *websocket.WebSocketServer

// SetWebSocketServer 设置全局WebSocket服务器实例
func SetWebSocketServer(server *websocket.WebSocketServer) {
	globalWebSocketServer = server
}

// getWebSocketServer 获取全局WebSocket服务器实例
func getWebSocketServer() *websocket.WebSocketServer {
	return globalWebSocketServer
}

// CreateRoomHandler 创建房间
func CreateRoomHandler(c *gin.Context) {
	var req struct {
		Name        string `json:"name" binding:"required"`
		Tag         string `json:"tag"`
		Password    string `json:"password"`
		Description string `json:"description"`
		MaxUsers    int    `json:"max_users"`
		Timeout     int    `json:"timeout"`
		CreatorID   string `json:"creator_id"`   // 添加创建者ID字段
		CreatorName string `json:"creator_name"` // 添加创建者名称字段
	}

	// 先尝试绑定JSON
	if err := c.ShouldBindJSON(&req); err != nil || req.Name == "" {
		fmt.Printf("绑定JSON失败或房间名为空: %v, name: %s\n", err, req.Name)
		c.JSON(http.StatusBadRequest, gin.H{"error": "房间名不能为空"})
		return
	}

	// 添加调试信息
	fmt.Printf("=== 后端创建房间调试信息 ===\n")
	fmt.Printf("请求体数据: %+v\n", req)
	fmt.Printf("CreatorID from body: %s\n", req.CreatorID)
	fmt.Printf("CreatorName from body: %s\n", req.CreatorName)

	// 优先从请求体获取创建者信息，如果没有则从请求头获取
	creatorIDStr := req.CreatorID
	creatorName := req.CreatorName

	if creatorIDStr == "" {
		creatorIDStr = c.GetHeader("X-User-Id")
		fmt.Printf("CreatorID from header: %s\n", creatorIDStr)
	}
	if creatorName == "" {
		creatorName = c.GetHeader("X-User-Name")
		fmt.Printf("CreatorName from header: %s\n", creatorName)
	}

	// 如果还是没有，尝试从查询参数获取
	if creatorIDStr == "" {
		creatorIDStr = c.Query("user_id")
		fmt.Printf("CreatorID from query: %s\n", creatorIDStr)
	}
	if creatorName == "" {
		creatorName = c.Query("user_name")
		fmt.Printf("CreatorName from query: %s\n", creatorName)
	}

	// 确保有创建者ID
	if creatorIDStr == "" {
		fmt.Printf("错误: 创建者ID为空\n")
		c.JSON(http.StatusBadRequest, gin.H{"error": "创建者ID不能为空"})
		return
	}

	creatorID, err := strconv.Atoi(creatorIDStr)
	if err != nil {
		fmt.Printf("错误: 创建者ID格式错误: %s\n", creatorIDStr)
		c.JSON(http.StatusBadRequest, gin.H{"error": "创建者ID格式错误"})
		return
	}

	fmt.Printf("最终使用的创建者ID: %d\n", creatorID)
	fmt.Printf("最终使用的创建者名称: %s\n", creatorName)
	fmt.Printf("========================\n")

	room := &models.Room{
		Name:        req.Name,
		CreatorID:   creatorID,
		CreatorName: creatorName,
		Tag:         req.Tag,
		Password:    req.Password,
		Description: req.Description,
		MaxUsers:    req.MaxUsers,
		Timeout:     req.Timeout,
	}
	err = models.CreateRoom(room)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "房间创建失败"})
		return
	}

	fmt.Printf("房间创建成功: ID=%d, Name=%s, Tag=%s\n", room.ID, room.Name, room.Tag)

	// 房间创建成功后，立即在WebSocket服务器中创建内存房间
	wsServer := getWebSocketServer()
	if wsServer != nil {
		// 根据房间类型创建相应的内存房间
		if req.Tag == "snake" || req.Tag == "gomoku" || req.Tag == "tictactoe" || req.Tag == "ruins" || req.Tag == "game" {
			// 创建游戏房间，使用数据库生成的房间ID
			roomIDStr := fmt.Sprintf("%d", room.ID)
			wsServer.CreateRoomFromDB(room)
			fmt.Printf("已创建WebSocket游戏房间: %s (类型: %s)\n", roomIDStr, req.Tag)
		} else {
			// 创建聊天房间
			wsServer.CreateRoomFromDB(room)
			fmt.Printf("已创建WebSocket聊天房间: %s\n", room.ID)
		}
	}

	c.JSON(http.StatusOK, gin.H{"room_id": room.ID, "room_name": req.Name})
}

// GetRoomsHandler 获取房间列表
func GetRoomsHandler(c *gin.Context) {
	rooms, err := models.GetAllRooms()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取房间列表失败"})
		return
	}

	// 构建返回的房间列表，用户数量完全由前端WebSocket管理
	var roomList []gin.H
	for _, room := range rooms {
		roomList = append(roomList, gin.H{
			"id":           room.ID,
			"name":         room.Name,
			"creator_id":   room.CreatorID,
			"creator_name": room.CreatorName,
			"tag":          room.Tag,
			"max_users":    room.MaxUsers,
			"is_playing":   room.IsPlaying,
			"created_at":   room.CreatedAt,
			"updated_at":   room.UpdatedAt,
		})
	}

	c.JSON(http.StatusOK, gin.H{"data": roomList})
}

// DeleteRoomHandler 删除房间
func DeleteRoomHandler(c *gin.Context) {
	roomID := c.Param("id")
	if roomID == "" {
		roomID = c.Query("room_id")
	}
	if roomID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "房间ID不能为空"})
		return
	}

	// 添加调试信息
	fmt.Printf("=== 删除房间调试信息 ===\n")
	fmt.Printf("房间ID: %s\n", roomID)

	// 获取当前用户ID
	userIDStr := c.GetHeader("X-User-Id")
	fmt.Printf("从请求头获取的用户ID: %s\n", userIDStr)

	if userIDStr == "" {
		userIDStr = c.Query("user_id")
		fmt.Printf("从查询参数获取的用户ID: %s\n", userIDStr)
	}

	userID, err := strconv.Atoi(userIDStr)
	if err != nil {
		fmt.Printf("用户ID转换失败: %s, 错误: %v\n", userIDStr, err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "用户ID格式错误"})
		return
	}

	fmt.Printf("最终用户ID: %d\n", userID)

	// 获取房间信息
	room, err := models.GetRoomByID(roomID)
	if err != nil {
		fmt.Printf("获取房间信息失败: %v\n", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取房间信息失败"})
		return
	}

	fmt.Printf("房间信息: ID=%d, 创建者ID=%d, 房间名=%s\n", room.ID, room.CreatorID, room.Name)

	// 检查权限：只有创建者可以删除房间
	if room.CreatorID != userID {
		fmt.Printf("权限检查失败: 房间创建者ID=%d, 当前用户ID=%d\n", room.CreatorID, userID)
		c.JSON(http.StatusForbidden, gin.H{"error": "只有房间创建者可以删除房间"})
		return
	}

	fmt.Printf("权限检查通过，开始删除房间\n")

	if err := models.DeleteRoomByID(roomID); err != nil {
		fmt.Printf("删除房间失败: %v\n", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除房间失败"})
		return
	}

	fmt.Printf("房间删除成功\n")
	fmt.Printf("========================\n")

	c.JSON(http.StatusOK, gin.H{"message": "房间删除成功"})
}

// SetRoomEmptySinceHandler 设置房间为空的时间
func SetRoomEmptySinceHandler(c *gin.Context) {
	roomID := c.Param("id")
	if roomID == "" {
		roomID = c.Query("room_id")
	}
	t := time.Now()
	if err := models.SetRoomEmptySince(roomID, t); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "设置失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "设置成功"})
}

// ClearRoomEmptySinceHandler 清空房间为空的时间
func ClearRoomEmptySinceHandler(c *gin.Context) {
	roomID := c.Param("id")
	if roomID == "" {
		roomID = c.Query("room_id")
	}
	if err := models.ClearRoomEmptySince(roomID); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "清空失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "清空成功"})
}

// GetRoomInfoHandler 获取房间信息
func GetRoomInfoHandler(c *gin.Context) {
	roomID := c.Param("id")
	if roomID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "房间ID不能为空"})
		return
	}

	room, err := models.GetRoomByID(roomID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取房间信息失败"})
		return
	}

	c.JSON(http.StatusOK, room)
}

// JoinRoomHandler 加入房间
func JoinRoomHandler(c *gin.Context) {
	roomID := c.Param("id")
	if roomID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "房间ID不能为空"})
		return
	}

	// 获取用户信息
	userIDStr := c.GetHeader("X-User-Id")
	if userIDStr == "" {
		userIDStr = c.Query("user_id")
	}

	userName := c.GetHeader("X-User-Name")
	if userName == "" {
		userName = c.Query("user_name")
	}

	if userIDStr == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "用户ID不能为空"})
		return
	}

	_, err := strconv.Atoi(userIDStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "用户ID格式错误"})
		return
	}

	// 检查房间是否存在
	_, err = models.GetRoomByID(roomID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "房间不存在"})
		return
	}

	// 清空房间为空时间（表示房间现在有用户）
	if err := models.ClearRoomEmptySince(roomID); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新房间状态失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "成功加入房间"})
}

// LeaveRoomHandler 离开房间
func LeaveRoomHandler(c *gin.Context) {
	roomID := c.Param("id")
	if roomID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "房间ID不能为空"})
		return
	}

	// 获取用户信息
	userIDStr := c.GetHeader("X-User-Id")
	if userIDStr == "" {
		userIDStr = c.Query("user_id")
	}

	if userIDStr == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "用户ID不能为空"})
		return
	}

	_, err := strconv.Atoi(userIDStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "用户ID格式错误"})
		return
	}

	// 检查房间是否存在
	_, err = models.GetRoomByID(roomID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "房间不存在"})
		return
	}

	// 设置房间为空时间
	t := time.Now()
	if err := models.SetRoomEmptySince(roomID, t); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新房间状态失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "成功离开房间"})
}
